package com.typhoon.extend.controller;

import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.net.URLDecoder;
import java.util.ArrayList;
import java.util.Enumeration;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.web.multipart.MultipartFile;
import org.springframework.web.multipart.MultipartHttpServletRequest;
import org.springframework.web.multipart.commons.CommonsMultipartResolver;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.alibaba.fastjson.serializer.SerializerFeature;
import com.typhoon.extend.constant.EntityError;
import com.typhoon.extend.util.PageHolder;
import com.typhoon.extend.util.ResponseUtils;

/**
 * Created by hujun on 2017/3/16.
 */
public class BaseController  {

    protected static final int RESULT_OK = EntityError.S_OK.getCode();
    protected static final int FAILT_STATUS = EntityError.SYSTEM_ERROR.getCode();

    protected static final String STATUS_KEY = "code";

    protected static final String DATA_KEY = "data";

    protected static final String MSG_KEY = "msg";

    protected Map<String, Object> results = new HashMap<String, Object>();
    //默认页大小为20
    protected PageHolder pageHolder = new PageHolder(20);

    private static final Logger logger = LoggerFactory.getLogger(BaseController.class);


    /**
     * @param response
     * @param status
     * @param status
     */
    public void putParamResult(HttpServletResponse response, int status) {
        Map<String, Object> results = new HashMap<String, Object>();
        results.put(STATUS_KEY, status);
        ResponseUtils.renderJson(response, JSONObject.toJSONString(results, SerializerFeature.WriteMapNullValue));
    }

    /**
     * @param response
     * @param status
     * @param msg
     */
    public void putParamResult(HttpServletResponse response, int status, String msg) {
        Map<String, Object> results = new HashMap<String, Object>();
        results.put(STATUS_KEY, status);
        results.put(MSG_KEY, msg);
        ResponseUtils.renderJson(response, JSONObject.toJSONString(results, SerializerFeature.WriteMapNullValue));
    }

    public void putParamResult(HttpServletResponse response, EntityError result) {
        Map<String, Object> results = new HashMap<String, Object>();
        results.put(STATUS_KEY, result.getCode());
        results.put(MSG_KEY, result.getMsg());
        ResponseUtils.renderJson(response, JSONObject.toJSONString(results, SerializerFeature.WriteMapNullValue));
    }

    /**
     * @param response
     * @param status
     * @param data
     */
    public void putParamResult(HttpServletResponse response, int status, Object data) {
        Map<String, Object> results = new HashMap<String, Object>();
        results.put(STATUS_KEY, status);
        results.put(DATA_KEY, data);
        ResponseUtils.renderJson(response, JSONObject.toJSONString(results, SerializerFeature.WriteMapNullValue));
    }

    /**
     * @param response
     * @param result
     * @param data
     */
    public void putParamResult(HttpServletResponse response, EntityError result, Object data) {
        Map<String, Object> results = new HashMap<String, Object>();
        results.put(STATUS_KEY, result.getCode());
        results.put(MSG_KEY, result.getMsg());
        results.put(DATA_KEY, data);
        ResponseUtils.renderJson(response, JSONObject.toJSONString(results, SerializerFeature.WriteMapNullValue));
    }

    /**
     * @param response
     * @param map
     */
    public void putParamResult(HttpServletResponse response, Map<String, Object> map) {
        ResponseUtils.renderJson(response, JSON.toJSONString(map));
    }

    /**
     * @param response
     * @param status
     * @param msg
     * @param key
     * @param value
     */
    public void putParamResult(HttpServletResponse response, int status, String msg, String key, Object value) {
        Map<String, Object> results = new HashMap<String, Object>();
        results.put(STATUS_KEY, status);
        results.put(MSG_KEY, msg);
        results.put(key, value);
        ResponseUtils.renderJson(response, JSONObject.toJSONString(results, SerializerFeature.WriteMapNullValue));
    }


    public void putSuccessResult(HttpServletResponse response) {
        Map<String, Object> results = new HashMap<String, Object>();
        results.put(STATUS_KEY, RESULT_OK);
        results.put(MSG_KEY, "OK");
        ResponseUtils.renderJson(response, JSONObject.toJSONString(results, SerializerFeature.WriteMapNullValue));
    }

    public void putFailtResult(HttpServletResponse response) {
        Map<String, Object> results = new HashMap<String, Object>();
        results.put(STATUS_KEY, FAILT_STATUS);
        results.put(MSG_KEY, "ERROR");
        ResponseUtils.renderJson(response, JSONObject.toJSONString(results, SerializerFeature.WriteMapNullValue));
    }

    public void putFailtResult(HttpServletResponse response, String msg) {
        Map<String, Object> results = new HashMap<String, Object>();
        results.put(STATUS_KEY, FAILT_STATUS);
        results.put(MSG_KEY, msg);
        ResponseUtils.renderJson(response, JSONObject.toJSONString(results, SerializerFeature.WriteMapNullValue));
    }

    public void putSuccessResultForMsg(HttpServletResponse response, String msg) {
        Map<String, Object> results = new HashMap<String, Object>();
        results.put(STATUS_KEY, RESULT_OK);
        results.put(MSG_KEY, msg);
        ResponseUtils.renderJson(response, JSONObject.toJSONString(results, SerializerFeature.WriteMapNullValue));
    }


    public void putSuccessResult(HttpServletResponse response, Object data) {
        Map<String, Object> results = new HashMap<String, Object>();
        results.put(STATUS_KEY, RESULT_OK);
        results.put(MSG_KEY, "OK");
        results.put(DATA_KEY, data);
        response.setContentType("application/json; charset=utf-8");
        response.setCharacterEncoding("utf-8");
        ResponseUtils.renderJson(response, JSONObject.toJSONString(results, SerializerFeature.WriteMapNullValue), null);
    }

    public void putSuccessResultForCoding(HttpServletResponse response, Object data, String coding) {
        Map<String, Object> results = new HashMap<String, Object>();
        results.put(STATUS_KEY, RESULT_OK);
        results.put(MSG_KEY, "OK");
        results.put(DATA_KEY, data);

        response.setContentType("application/json; charset=utf-8");
        response.setCharacterEncoding("utf-8");
        ResponseUtils.renderJson(response, JSONObject.toJSONString(results, SerializerFeature.WriteMapNullValue), coding);
    }

    public void putSuccessResultForHeader(HttpServletResponse response, String data, Map<String, String> map) {
        response.setContentType("application/json; charset=utf-8");
        response.setCharacterEncoding("utf-8");
        if (map != null) {
            for (String key : map.keySet()) {
                response.addHeader(key, map.get(key));
            }
        }
        ResponseUtils.renderJson(response, data, null);
    }


    public void putSuccessResult(HttpServletResponse response, String msg, Object data) {
        Map<String, Object> results = new HashMap<String, Object>();
        results.put(STATUS_KEY, RESULT_OK);
        results.put(MSG_KEY, msg);
        results.put(DATA_KEY, data);
        ResponseUtils.renderJson(response, JSONObject.toJSONString(results, SerializerFeature.WriteMapNullValue));
    }


    public String getHeaderParam(HttpServletRequest request, String param) {

        String paramValue = request.getHeader(param);
        if (StringUtils.isNotBlank(paramValue)) {
            String decToken = null;
            try {
                decToken = URLDecoder.decode(paramValue, "UTF-8");
            } catch (UnsupportedEncodingException e) {
                logger.warn("getHeaderParam.decoder is e.:" + e.getMessage());
            }
            return decToken;
        }
        return null;
    }

    public String getParam(HttpServletRequest request, String param) {
        String paramStr = request.getParameter(param);
        return paramStr;
    }

    public int getInt(HttpServletRequest request, String param) {
        String paramStr = request.getParameter(param);
        if (StringUtils.isNotBlank(paramStr)) {
            return Integer.valueOf(paramStr);
        }
        return 0;
    }

    public long getLong(HttpServletRequest request, String param) {
        String paramStr = request.getParameter(param);
        if (StringUtils.isNotBlank(paramStr)) {
            return Long.valueOf(paramStr);
        }
        return 0;
    }


    public String getRemoteIP(HttpServletRequest request) {
        String ipaddr = request.getHeader("X-nginx-real-ip");
        if (StringUtils.isNotBlank(ipaddr)) {
            return ipaddr;
        }

        ipaddr = request.getHeader("X-Real-IP");
        if (StringUtils.isNotBlank(ipaddr)) {
            return ipaddr;
        }

        ipaddr = request.getHeader("X-Forwarded-For");
        if (StringUtils.isNotBlank(ipaddr)) {
            return ipaddr;
        }

        ipaddr = request.getHeader("X-Remote-Addr");
        if (StringUtils.isNotBlank(ipaddr)) {
            return ipaddr;
        }

        ipaddr = request.getHeader("HTTP_X_FORWARDED_FOR");
        if (StringUtils.isNotBlank(ipaddr)) {
            return ipaddr;
        }

        ipaddr = request.getHeader("Proxy-Client-IP");
        if (StringUtils.isNotBlank(ipaddr)) {
            return ipaddr;
        }

        ipaddr = request.getHeader("WL-Proxy-Client-IP");
        if (StringUtils.isNotBlank(ipaddr)) {
            return ipaddr;
        }

        ipaddr = request.getHeader("HTTP_X_REAL_IP");
        if (StringUtils.isNotBlank(ipaddr)) {
            return ipaddr;
        }

        if (StringUtils.isBlank(ipaddr)) {
            ipaddr = request.getRemoteAddr();
        }
        return ipaddr;
    }


    public String getRequestURL(HttpServletRequest request) {
        if (request == null) {
            return "";
        }
        String url = "";
        url = request.getContextPath();
        url = url + request.getServletPath();

        Enumeration names = request.getParameterNames();
        int i = 0;
        if (!"".equals(request.getQueryString())
                || request.getQueryString() != null) {
            url = url + "?" + request.getQueryString();
        }

        if (names != null) {
            while (names.hasMoreElements()) {
                String name = (String) names.nextElement();
                if (i == 0) {
                    url = url + "?";
                } else {
                    url = url + "&";
                }
                i++;

                String value = request.getParameter(name);
                if (value == null) {
                    value = "";
                }

                url = url + name + "=" + value;
                try {
                    // java.net.URLEncoder.encode(url, "ISO-8859");
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
        }
        try {
            // String enUrl = java.net.URLEncoder.encode(url, "utf-8");
        } catch (Exception ex) {
            ex.printStackTrace();
        }

        return url;
    }

    protected void outputJsonp(HttpServletRequest request, HttpServletResponse response, final Object rs) {
        try {
            String callback = request.getParameter("jsoncallback");
            if (StringUtils.isBlank(callback)) {
                callback = "jsoncallback";
            }
            String writer = callback + "( " + JSONObject.toJSONString(rs) + " )";

            response.setContentType("text/html");
            response.setCharacterEncoding("utf-8");
            response.setHeader("Pragma", "No-cache");
            response.setDateHeader("Expires", 0);
            response.setHeader("Cache-Control", "no-cache");
            response.getWriter().write(writer);
            response.getWriter().flush();
            response.getWriter().close();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    /**
     * 从request中获取参数
     *
     * @param request
     * @return
     */
    public Map<String, String> getParamsFromRequest(HttpServletRequest request) {
        Map<String, String> results = new HashMap<>();
        Map<String, String[]> param = request.getParameterMap();
        if (param != null && param.size() > 0) {
            for (Map.Entry<String, String[]> entry : param.entrySet()) {
                results.put(entry.getKey(), entry.getValue()[0]);
            }
        }
        return results;
    }

    /**
     * 导出excel
     *
     * @param response
     * @param wb
     */
//    public void exportExcel(HttpServletResponse response, HSSFWorkbook wb, String fileName) {
//        if (wb == null) {
//            throw new RuntimeException("没有导出的对象...");
//        }
//        if (fileName == null) {
//            fileName = "defaultExcel-" + System.currentTimeMillis();
//        }
//        OutputStream out = null;
//        try {
//            response.setContentType("application/vnd.ms-excel;charset=utf-8");
//            fileName = java.net.URLEncoder.encode(fileName, "UTF-8");
//            String contentDisposition = "attachment;filename=" + fileName + ".xls";
//            response.setHeader("Content-Disposition", contentDisposition);
//
//            response.addHeader("Pragma", "no-cache");
//            response.addHeader("Cache-Control", "no-cache");
//            out = response.getOutputStream();
//            wb.write(out);
//        } catch (RuntimeException e) {
//            throw e;
//        } catch (Exception e) {
//            throw new RuntimeException("导出excel文件出错...");
//        } finally {
//            if (out != null) {
//                try {
//                    out.close();
//                } catch (IOException e) {
//                    e.printStackTrace();
//                }
//            }
//
//        }
//    }

    /**
     * 获取上传得文件
     * @param request
     * @return
     */
    public List<MultipartFile> getMultipartFile(HttpServletRequest request) {
        List<MultipartFile> result = new ArrayList<>();
        CommonsMultipartResolver multipartResolver = new CommonsMultipartResolver(request.getSession().getServletContext());
        if (multipartResolver.isMultipart(request)) {
            MultipartHttpServletRequest multiRequest = (MultipartHttpServletRequest) request;
            //获取multiRequest 中所有的文件名
            Iterator iter = multiRequest.getFileNames();
            while (iter.hasNext()) {
                //一次遍历所有文件
                MultipartFile file = multiRequest.getFile(iter.next().toString());
                if (file != null) {
                    result.add(file);
                }
            }
        }
        return result;
    }
}
